import { throttle } from "../utils/throttle";
import { ProgressLocation, Uri, window } from "vscode";
import { languageService } from "../services/LanguageService";
import { Languages, languagesMapLeetCodeStr } from "../common/Languages";
import { submitSolution, SubmitSolutionArgs } from "../apis/submit-solution";
import { leetCodeOutputChannel } from "../output/QuestionOutputChannel";
import { wait } from "../utils/wait";
import { submitCheck } from "../apis/submit-check";
import { questionExplorerTreeDataProvider } from "../view/QuestionExplorerTreeDataProvider";

/**
 * 提交代码
 */
export const submitQuestion = throttle(async (uri: Uri) => {
    return window.withProgress({location: ProgressLocation.Notification}, async p => {
        p.report({message: "提交解决方案..."});
        const languages = languageService.getLanguagesByFsPath(uri.fsPath);
        if (!languages) {
            return Promise.reject("获取文件语言失败");
        }
        return languageService.getTestOrSubmitQuestionData(languages).then(value => {
            const {titleSlug, id, code} = value;
            return submitSolution(new SubmitSolutionArgs(titleSlug, id, languagesMapLeetCodeStr.get(languages)!!, code,))
                .then(value => check(value.id, languages));
        });
    });
}, 10000, (value) => {
    if (value[1]) {
        window.showInformationMessage("思考10秒之后再提交吧", {});
    }
});

const check = async (id: string, lang: Languages): Promise<void> => {
    return submitCheck({id}).then(res => {
        if (res.state === "SUCCESS") {
            leetCodeOutputChannel.show().clear().appendTime();
            console.log(res);
            if (res.run_success) {
                let result = "";
                if (res.total_correct === res.total_testcases) {
                    questionExplorerTreeDataProvider.refresh();
                    leetCodeOutputChannel
                        .appendLine("执行用时：" + res.status_runtime + " ，在所有 " + lang + " 提交中击败了 " + parsePercentile(res.runtime_percentile) + "% 的用户")
                        .appendLine("内存消耗：" + res.status_memory + " ，在所有 " + lang + " 提交中击败了 " + parsePercentile(res.memory_percentile) + "% 的用户");
                } else {
                    leetCodeOutputChannel.appendLine("输入：\n" + res.last_testcase)
                        .appendLine("输出：\n" + res.code_output)
                        .appendLine("预期结果：\n" + res.expected_output);
                }
                leetCodeOutputChannel.appendLine(result + "通过测试用例：" + res.total_correct + " / " + res.total_testcases);
            } else {
                if (res.status_msg === "Compile Error") {
                    leetCodeOutputChannel.appendLine("编译错误")
                        .appendLine(res.full_compile_error ?? "");
                } else if (res.status_msg === "Runtime Error") {
                    leetCodeOutputChannel.appendLine("运行时错误")
                        .appendLine(res.full_runtime_error ?? "");
                } else if (res.status_msg === "Memory Limit Exceeded") {
                    leetCodeOutputChannel.appendLine("超出内存限制");
                } else if (res.status_msg === "Time Limit Exceeded") {
                    leetCodeOutputChannel.appendLine("超出时间限制");
                } else {
                    leetCodeOutputChannel.appendLine(JSON.stringify(res));
                }
            }
            return;
        }
        return wait(200).then(() => check(id, lang));
    });
};

const parsePercentile = (percentile?: number) => {
    const res = String(percentile ?? 0);
    let end = res.length;
    const pointIndex = res.indexOf(".");
    if (pointIndex >= 0) {
        end = pointIndex + 2;
    }
    return res.substring(0, end);
};